from direct.task import Task
from TaskDefine import task_CommandDispatch
from QCmdQueue import QCmdQueue
from QCmdParser import QCmdParser
from Cube.command.QCommand import QCommand, DefaultCommandKlassList, QCmdIdle
from EventDefine import event_CMDPIPE_CMDEXECDONE

class QCmdInputPipe:
    def __init__(self, CmdDispatchPeriods=0.1, SyncMode=True):
        self.SyncMode = SyncMode
        self.NullCmdItemSend = QCmdIdle().Send
        self.CmdDispatchPeriods = CmdDispatchPeriods
        self.CmdQueue = QCmdQueue(SyncMode = SyncMode)
        self.CmdParser = QCmdParser()
        QCommand.CmdQueue = self.CmdQueue
        self.CmdHandleRegist = self.CmdParser.CmdHandleRegist
        self.CmdDispatchTask = None

        self.DefaultCommandRegist(DefaultCommandKlassList)

    def DefaultCommandRegist(self, cmdKlassList):
        for cmdKlass in cmdKlassList:
            self.CmdHandleRegist(cmdKlass())

    def CmdDispatchPeriodsReset(self, value):
        if self.CmdDispatchPeriods != value:
            self.CmdDispatchPeriods = value
            if self.CmdDispatchTask is not None:
                taskMgr.remove(self.CmdDispatchTask)
            self.CommandDispatchStart()

    def CommandDispatchStart(self):
        print "CmdDispatchPeriods:", self.CmdDispatchPeriods
        self.CmdDispatchTask = taskMgr.doMethodLater(self.CmdDispatchPeriods,
                                                     self.CommandDispatchTask,
                                                     task_CommandDispatch["name"]
                                                     )

    # override it
    def CommandDispatchTask(self, task):
        self.ExecutionComandUpdate()
        cmdList = self.CmdQueue.ExeCmdListExtract()
        #print cmdList
        self.CmdQueue.Clear()
        #print "CmdExecStart"
        self.CmdParser.ParsingCmdList(cmdList)
        #print "CmdExecDone"
        messenger.send(event_CMDPIPE_CMDEXECDONE, [self.CmdDispatchPeriods])  # do logic update
        #self.TestPatternSend()  # only use it in testing, mark it
        if self.SyncMode:
            self.CmdQueue.SendOutCmdBufferLoad()
        return Task.again

    # override it
    def ExecutionComandUpdate(self):
        self.CmdQueue.ExeCmdQueueMerge()  # merge ExeCmdQueue with InputCmdQueue

    def NullCmdPush(self, CmdBuffer=None):
        self.NullCmdItemSend(CmdBuffer)

    def destroy(self):
        taskMgr.remove(task_CommandDispatch["name"])

    # only use in testing
    def TestPatternSend(self):
        self.NullCmdItemSend()
